package com.hjc.demo.netty.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.net.SocketAddress;

public class NettyClient {

    private static Bootstrap setUp() {
        EventLoopGroup bossGroup = new NioEventLoopGroup();

        Bootstrap bs = new Bootstrap();

        return bs.group(bossGroup)
                .channel(NioSocketChannel.class)
                .option(ChannelOption.SO_KEEPALIVE, true)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        // marshalling 序列化对象的解码
//                  socketChannel.pipeline().addLast(MarshallingCodefactory.buildDecoder());
                        // marshalling 序列化对象的编码
//                  socketChannel.pipeline().addLast(MarshallingCodefactory.buildEncoder());
                        socketChannel.pipeline().addLast(new ChannelOutboundHandlerAdapter(){
                            @Override
                            public void bind(ChannelHandlerContext ctx, SocketAddress localAddress, ChannelPromise promise) throws Exception {
                                System.out.println("bind...");
                                ctx.channel();

                                super.bind(ctx, localAddress, promise);
                            }

                            @Override
                            public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) throws Exception {
                                System.out.println("connect...");
                                super.connect(ctx, remoteAddress, localAddress, promise);
                            }

                            @Override
                            public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
                                System.out.println("disconnect...");
                                super.disconnect(ctx, promise);
                            }

                            @Override
                            public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
                                System.out.println("close...");
                                super.close(ctx, promise);
                            }

                            @Override
                            public void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
                                System.out.println("deregister...");
                                super.deregister(ctx, promise);
                            }

                            @Override
                            public void read(ChannelHandlerContext ctx) throws Exception {
                                System.out.println("read...");

                                super.read(ctx);
                            }

                            @Override
                            public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
                                System.out.println("write...");
                                super.write(ctx, msg, promise);
                            }

                            @Override
                            public void flush(ChannelHandlerContext ctx) throws Exception {
                                System.out.println("flush...");
                                super.flush(ctx);
                            }
                        });
                        // 处理来自服务端的响应信息
                        socketChannel.pipeline().addLast(new ClientHandler());
                    }
                });
    }


    public static void start(String host, int port) throws InterruptedException {
        Bootstrap bootstrap = setUp();
        // 客户端开启
        ChannelFuture cf = bootstrap.connect(host, port).sync();
        cf.channel().closeFuture().sync();
    }


}
